package io.github.yotta.export.web.controller;

import io.github.yotta.common.api.exception.ServiceException;
import io.github.yotta.export.core.enums.DataExportStatus;
import io.github.yotta.export.core.model.DataExportResult;
import io.github.yotta.export.core.provider.FileProvider;
import io.github.yotta.export.web.iface.ExportTaskCache;
import io.github.yotta.export.web.model.ExportTaskResult;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Paths;

/**
 * @author yotta
 * @date 2023/10/31 15:14
 */
@RestController
@RequestMapping("/data/export/{name}")
@SuppressWarnings({"unused"})
public abstract class DataExportController {


    private final FileProvider fileProvider;
    private final ExcelExportProcessor excelProcessor;
    private final ExportTaskCache exportTaskCache;

    protected DataExportController(FileProvider fileProvider, ExcelExportProcessor excelProcessor,
                                   ExportTaskCache exportTaskCache) {
        this.fileProvider = fileProvider;
        this.excelProcessor = excelProcessor;
        this.exportTaskCache = exportTaskCache;
    }

    @PostMapping("/sync")
    public ExportTaskResult export(HttpServletResponse response, @PathVariable("name") String name,
                                   @RequestBody String exportParamJson) {
        return excelProcessor.process(name, exportParamJson);
    }

    @PostMapping("/syncAndDown")
    public void syncAndDown(HttpServletResponse response, @PathVariable("name") String name,
                            @RequestBody String exportParamJson) throws IOException {
        ExportTaskResult exportTaskResult = excelProcessor.process(name, exportParamJson);
        DataExportResult dataExportResult = exportTaskResult.getDataExportResult();
        if (dataExportResult == null || DataExportStatus.SUCCESS.getCode() != dataExportResult.getStatus()) {
            throw new ServiceException("export fail");
        }
        download(response, dataExportResult.getExportFilePath(), dataExportResult.getExportFileName());
    }

    @PostMapping("/async")
    public ExportTaskResult exportAsync(HttpServletResponse response, @PathVariable("name") String name,
                                        @RequestBody String exportParamJson) {
        return excelProcessor.processAsync(name, exportParamJson);
    }

    @GetMapping("/async/{taskId}")
    public ExportTaskResult exportAsync(@PathVariable(name = "taskId") String taskId,
                                        @PathVariable(name = "name") String taskName) {
        return exportTaskCache.get(taskId);
    }


    @GetMapping("download")
    public void download(HttpServletResponse response,
                         @RequestParam("path") String path,
                         @RequestParam("fileName") String exportFileName) throws IOException {
        InputStream inputStream = this.fileProvider.openFile(path);
        // 使用spring的工具类把resource中的文件转换成一个字节数组
        byte[] bytes = FileCopyUtils.copyToByteArray(inputStream);
        // 使用response设置响应消息头
        response.setContentType("application/octet-stream");
        String fileName = Paths.get(path).getFileName().toString();
        response.setContentLength(bytes.length);
        String encodeFileName = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + encodeFileName + "\"");
        response.setContentLengthLong(bytes.length);
        // 输出字节数组
        response.getOutputStream().write(bytes, 0, bytes.length);
    }


}
